/**
 * JAVACC DEMO 1.0
 */
package com.apache.seq.service.plugins;

import com.apache.api.manager.PluginConnector;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.database.constant.SystemTools;
import com.apache.database.constant.Validator;
import com.apache.seq.entity.Seq;
import com.apache.seq.manager.SeqManager;
import com.apache.seq.service.impl.SeqHelperUtil;
import com.apache.tools.DateUtils;
import org.apache.log4j.Logger;

/**
 * description:  获得下一个序列值
 *
 * @author Hou Dayu 创建时间：2016-4-27
 */
public class SeqNextValuePlugin implements PluginConnector {

    private Logger log = Logger.getLogger(SeqNextValuePlugin.class);

    private SeqManager seqManager;

    private transient static Object synchronizedObj = new Object();

    /**30位*/
    //private final String headStr = "000000000000000000000000000000";

    /**
     * TODO 获得下一个序列值 <br>
     * 参数说明:<br>
     * seqEname 序列名<br>
     * strLen 字符串长度
     * seqMode 是否按天计算(0:不按天计算(默认);1:按天计算;)
     *
     * @see com.apache.api.manager.PluginConnector#execute(com.apache.api.vo.ParamsVo)
     */
    public Object execute(ParamsVo vo) throws Exception {
        ResultEntity result = new ResultEntity();
        result.setResult("true");
        try {
            synchronized (synchronizedObj) {
                String seqEname = String.valueOf(vo.getParams("seqEname"));
                String len = String.valueOf(vo.getParams("strLen"));//字符串长度，不足会在前面自动填充0
                String seqMode = Validator
                        .getDefaultStr(String.valueOf(vo.getParams("seqMode")), "0");//0/1
                if (Validator.isNotNull(seqEname)) {
                    String nextValue = getNextValueNum(seqEname, Validator.getDefaultStr(len, "0"),
                            seqMode);
                    result.setEntity(nextValue);
                    result.setMessage("查询成功");
                    log.info("nextValue=" + nextValue + "; seqEname=" + seqEname);
                } else {
                    result.setResult("false");
                    result.setMessage("序列名为空");
                }
            }
        } catch (Exception e) {
            result.setResult("false");
            log.error("执行序列查询失败 ", e);
            result.setMessage("查询序列失败！");
        }
        return result;
    }

    /**
     * 根据序列名获得下一个值
     *
     * @param seqEname 序列名称
     * @return long 数字
     */
    private String getNextValueNum(String seqEname, String len, String seqMode) {
        String key = "seq_" + seqEname;
        log.info("seqEname=" + seqEname + "; len=" + len);
        Seq seq = (Seq) SystemTools.getInstance().getCache("").getCacheObjectByKey(key);
        ParamsVo<Seq> pvo = new ParamsVo<Seq>();
        if (null == seq) {
            pvo.setInfoId(seqEname);
            seq = (Seq) seqManager.getInfoById(pvo);
        }
        String nowStr = DateUtils.Now.fmt_yyyyMMdd_HHmmssSSS();
        String nextSeq = "";
        long nextValue = 1l;
        if (Validator.isEmpty(seq)) {
            seq = new Seq();
            seq.setSeqCname(seqEname);
            seq.setSeqEname(seqEname);
            seq.setStepValue(1);//默认步长
            seq.setStartValue(0L);//起始值
            seq.setFirstGetTime(nowStr);//第一次跟新时间
            seq.setLastGetTime(nowStr);//最后获取时间
            seq.setUpdateCount(0L);//更新次数
            seq.setNextValue(2l);
            if ("1".equals(seqMode)) {//若日期!=今日,则Seq重置1开始
                nextSeq = SeqHelperUtil.calculateNextSeq(seqEname, seq, Integer.parseInt(len));
            } else {
                nextSeq = SeqHelperUtil.calculateNextSeq2(seqEname, 1, Integer.parseInt(len));
            }
            pvo.setObj(seq);
            seqManager.saveInfo(pvo);
            log.info("序列 save=" + seq);
        } else {
            long startValue = seq.getStartValue() == null ? 0L : seq.getStartValue().longValue();
            nextValue = seq.getNextValue() == null ? 0L : seq.getNextValue().longValue();
            long updateCount = seq.getUpdateCount() == null ? 0L : seq.getUpdateCount().longValue();
            if (nextValue <= 0L) {
                if (startValue > 0L) {
                    nextValue = startValue;
                } else {
                    nextValue = 1L;
                }
            }
            int stepValue = seq.getStepValue() == null ? 1 : seq.getStepValue().intValue();
            if (stepValue <= 0) {
                stepValue = 1;
            }
            seq.setUpdateCount(updateCount + 1);//获取次数
            seq.setNextValue(nextValue + stepValue);
            //log.info("nextValue=" + nextValue + ";step=" + stepValue);
            log.info("序列 edit=" + seq);
            if ("1".equals(seqMode)) {
                nextSeq = SeqHelperUtil.calculateNextSeq(seqEname, seq, Integer.parseInt(len));
            } else {
                nextSeq = SeqHelperUtil
                        .calculateNextSeq2(seqEname, nextValue, Integer.parseInt(len));
            }
            seq.setLastGetTime(nowStr);//最后获取时间
            //pvo.setObj(seq);
            SeqHelperUtil.SeqThread(seq);
            //seqManager.editInfo(pvo);
        }
        SystemTools.getInstance().getCache("").createCacheObject(key, seq);
        return nextSeq;
    }

    public void setSeqManager(SeqManager seqManager) {
        this.seqManager = seqManager;
    }

}
